import toolRandom from "./tool-random";

let lockObj = {};

const sleep = (delay) => new Promise((resolve) => setTimeout(resolve, delay));

/**
 * 缓存方法
 * @param {*} key
 * @param {*} val
 * @param {*} expireTime
 */
function set(key, val, expireTime) {
  localStorage.setItem(key, JSON.stringify(val));
  localStorage.setItem(key + "expireTime", expireTime);
}

function get(key) {
  let val = localStorage.getItem(key);
  if (!val) {
    return;
  }
  let expireTime = parseInt(localStorage.getItem(key + "expireTime"));
  if (Date.now() > expireTime) {
    return;
  }
  try {
    return JSON.parse(val);
  } catch (e) {
    return val;
  }
}

async function cache(key, fun, time = 1000 * 60 * 60 * 24 * 7) {
  if (!key) {
    return;
  }
  // 锁定
  let lockKey = lock(key);
  if (lockKey) {
    try {
      let val = get(key);
      if (!val && fun && fun instanceof Function) {
        val = await fun();
        set(key, val, Date.now() + time);
      }
      return val;
    } finally {
      // 解锁
      unLock(key, lockKey);
    }
  } else {
    await sleep(300);
    return cache(key, fun, time);
  }
}

function lock(key) {
  if (!lockObj[key]) {
    return (lockObj[key] = toolRandom.randomStr(10));
  }
}

function unLock(key, lockKey) {
  if (lockObj[key] === lockKey) {
    delete lockObj[key];
    return true;
  }
  return false;
}

const toolCache = {
  cache,
  lock,
  unLock,
};

export default toolCache;
